大家好,我是 Eric。
上一篇文章中,我們先看到負責管理頁面架構的語意化標籤。
今天,我們再進一步了解跟「內容」有關的 HTML 標籤,以及 HTML 中的屬性 (attributes) 與 WordPress 的編碼標準 (coding standard)。
從 W3C 的規範中,我們可以查閱不同語意化標籤的定義,以及相關的用法與限制。但坦白說,我自己也沒有讀完,大多數的語意問題也都是在編寫的過程中,逐一偵錯。
一般來說,常見的標籤有以下幾種:
根據 W3C 的定義,<p>
標籤代表「段落」。
在 WordPress 5 之後的區塊編輯器中,每按一次 Enter 鍵,便會自動建立一個新的 <p>
標籤。
這邊值得注意的是,<p>
並不能包含項目列表 <ul>
與 <ol>
,這是因為 HTML 的標籤,是網頁的「結構標籤」,協助瀏覽器了解網頁架構,而不是「邏輯標籤」,符合使用者想像的區塊空間。
舉例來說:
<p> 這是我認為論述應該要有的要素:
<ul>
<li> 核心論點 </li>
<li> 輔助事實 </li>
<li> 反證論點 </li>
<li> 駁斥反證論點 </li>
<li> 結論 </li>
</ul>
如果沒有包含上述要素的話,就是不完全的論述。</p>
在經過瀏覽器轉譯後,會變成:
<p> 這是我認為論述應該要有的要素:</p>
<ul>
<li> 核心論點 </li>
<li> 輔助事實 </li>
<li> 反證論點 </li>
<li> 駁斥反證論點 </li>
<li> 結論 </li>
</ul>
<p>如果沒有包含上述要素的話,就是不完全的論述。</p>
嚴格說起來,<div>
並不能稱為「語意化」標籤,
因為它的作用,是在告訴瀏覽器:「這裡有一個區塊。」
由於 <div>
賦予開發人員相當高的彈性,
因此廣泛用於各種場合,甚至到了濫用的地步。
反正不知道要用什麼的話,用
<div>
就沒問題了。
但這種做法並不符合 HTML5 的演化方向,
所以建議還是在適當的場合使用符合情境的語意化標籤。
那什麼時候需要用 <div>
呢?
在 HTML5 中,有些人會濫用 <section>
,將其作為內容的容器,但忽略了 <section>
跟 <p>
一樣,是「結構標籤」,而非「邏輯標籤」。
如果想要製作一個內容容器時,用 <div>
會比 <section>
還要合適。
顧名思義,就是標記圖片的標籤。
基本的語法 (syntax) 如下:
<img src="圖片位址" alt="替代文字" />
至於與圖片有關的其他屬性,如 srcset
與 width
等,並非本次的重點,這裡就先不贅述。
這個廣泛用於所有連結,基本語法如下:
<a href="連結位置" target="開啟方式">錨點文字</a>
開啟方式,主要有 _blank
與 _self
兩種,前者會開啟新視窗/頁籤,後者則是在當前視窗/頁籤中開啟連結頁面。
在 SEO 的領域中,標題標籤 <h1>
~ <h6>
是常常拿出來討論的話題。由於這些標題具有階級關係,因此在撰寫時需要特別注意。有些寫作風格認為一個頁面中只能存在一個 <h1>
標籤,但如果查閱 W3C 的標準,會發現這種說法並不完全正確。
由於相同階級的標題,會具有相同的權重,因此如果一個頁面中有多個 <h1>
標籤,對瀏覽器而言,代表有多個權重最高的標題。
但如果未規劃好位階的話,那就像是讀書畫重點時,將整個段落全部畫重點一樣,失去了「重點」的意義了。
表格元素,基本的語法為:
<table>
<tr>
<th>第一欄的欄位標題</th>
<th>第二欄的欄位標題</th>
</tr><!-- 第一列 -->
<tr>
<td>第二列第一欄儲存格</td>
<td>第二列第二欄儲存格</td>
</tr><!-- 第二列 -->
<tr>
<td>第三列第一欄儲存格</td>
<td>第三列第二欄儲存格</td>
</tr><!-- 第三列 -->
</table>
然而,隨著回應式網頁設計 (responsive web design) 的發展,使用 <table>
的比例開始降低,因為 <table>
在版面的調整上限制較多,較難真正做到回應式的變化。
我們從〈Twenty Twenty〉的 searchform.php 中,可以看到以下的程式碼:
//searchform.php Line 22
<form role="search" <?php echo $aria_label; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped above. ?> method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<label for="<?php echo esc_attr( $unique_id ); ?>">
<span class="screen-reader-text"><?php _e( 'Search for:', 'twentytwenty' ); // phpcs:ignore: WordPress.Security.EscapeOutput.UnsafePrintingFunction -- core trusts translations ?></span>
<input type="search" id="<?php echo esc_attr( $unique_id ); ?>" class="search-field" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder', 'twentytwenty' ); ?>" value="<?php echo get_search_query(); ?>" name="s" />
</label>
<input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button', 'twentytwenty' ); ?>" />
</form>
上述的範例是站內搜尋的搜尋欄位,我們可以知道,<form>
可以用來告訴瀏覽器:「接下來整個區塊是表單」。<form>
這個標籤,有 2 個特殊的屬性 (attributes,詳見下一段):method
與 action
。action
決定提交表單後,要前往哪個頁面,method
則決定了資料要以何種方式傳遞給 action
到達的頁面,常見的方式有兩種:
get
: 這種方法會將表單的資料用明碼 (未加密) 的方式,轉變成網址的查詢參數 (譬如: https://example.com/?s=7777)。通常只有搜尋表單會用這種方式儲存表單資訊。post
: 這種方法則是透過 HTTP 標頭的方法傳遞資料,不會直接顯示在網址上。通常對於需要加密的使用者資料,都會使用這個方法傳遞。其中 <input>
是表單的基本元素,代表輸入給表單的資料。根據需求不同,可以透過 type
這個屬性,代表不同的表單欄位格式,以下簡介幾種:
text
: 單行文字表單,譬如填寫姓名與地址。password
: 密碼表單,無法複製欄位裡的值。checkbox
: 核取方塊,一般所謂的「可複選」的欄位使用。radio
: 選項按鈕,一般所謂的「單選」欄位使用。透過相同的屬性 name
來決定是否屬於同一個選項群組。email
: 電子郵件位址,在部分手機的瀏覽器上,會顯示相對應的鍵盤。tel
: 電話,在部分手機的瀏覽器上,會顯示相對應的鍵盤。submit
: 提交按鈕,點擊後會開始執行 <form>
中指定的行動。透過 value
這個屬性,指定提交按鈕內欲顯示的文字。如 <input type="submit" value="點我送出" />
。與 <input>
對應的,是 <label>
這個標籤,通常 <label>
會使用 for="{{input id}}"
這個屬性,告訴瀏覽器這個標籤屬於哪一項欄位。
回到我們一開始的 header.php 檔案。
<?php
/**
* Header file for the Twenty Twenty WordPress default theme.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package WordPress
* @subpackage Twenty_Twenty
* @since 1.0.0
*/
?><!DOCTYPE html>
<html class="no-js" <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0" >
<link rel="profile" href="https://gmpg.org/xfn/11">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php
wp_body_open();
?>
<header id="site-header" class="header-footer-group" role="banner">
我們可以發現,每個標籤後面,都有若干個 xxx="ooo" 的「屬性」。
不同的標籤,支援的屬性都略有不同,但不論是哪一種標籤,以下 3 種屬性必定是共通的:
class
這個屬性,是用來將元素分類,供 CSS 選擇器使用,使用同樣的 class
,往往代表著這些元素會有相同的樣式。id
頁面中元素的識別碼。正因為是識別碼,因此在同一個頁面中,不能出現重複的 id
。和 class
一樣可以作為 CSS 選擇器的標的。style
有時候,我們會加入 style
這個屬性,用來標註內嵌樣式 (inline style)。必須注意的是,內嵌樣式並沒有辦法實踐 RWD 的設計,因此如果有需要回應式設計的樣式,必須透過 CSS 來定義。除了上述三種共通的屬性外,另一種屬性稱為資料屬性 (data attributes),其表現的方式就會是 data-xxx="ooo"
。
通常資料屬性是要將特定資料傳遞給 JavaScript 做使用,因此在這裡就不多加贅述。
編碼標準 (coding standard) 是所有專案中最重要,卻也最容易被忽略的部分。
就像是每個作家會有不同的寫作風格,每個開發人員撰寫程式碼的風格也不盡相同。為了避免新加入的開發人員無法理解程式碼背後的運作邏輯,因此大多數的開源專案都會訂立編碼標準,用來維持程式碼品質。
透過 WordPress 的官方文件,我們可以了解 WordPress 對 HTML 程式碼的要求有以下幾點:
<img>
,必須使用自我結尾標記 (self-closing tag),例如 <img src="..." alt="... />
。<div class="class" id="id>
<p class="paragraph" id="p1"><!-- 這裡用縮排表示 p 是在 div 之下 -->
</p>
</div>
<!--- 這個是註解 --->
。由於不同的開發者編碼習慣不同,因此註解對於新進開發者了解目前程式碼的功用有相當顯著的幫助。以 Twenty Twenty 來看,註解的功用,主要在註記區塊的範圍。class
與 id
的先後順序最好統一,這是因為後面討論 PHP,使用規則運算式 (regular expression 或 RegEX) 時,統一的順序可以降低比對的困難度。今天的內容主要包含了 HTML 中常見的語意化標籤,以及 HTML 會使用的共通屬性 class
、id
與 style
。除此之外,也說明了為什麼需要「編碼標準」。
如果今天是只有自己會維護的專案,那麼是否符合編碼標準,並非強制的。然而,如果這個專案是需要交接的,或者是開源專案,那麼遵守編碼標準,對於其他工程師而言,可以節省許多重新理解編碼架構的功夫。
截至目前為止,我們的討論都是針對頁面上實際看得到的要素:<body>
內的內容進行說明。下一章,我們要開始走進稍微抽象一點的 <head>
的世界,解說跟識別網頁相關的「中繼資料」與掌管網頁肉體 CSS 與靈魂 JavaScript 的區塊。